#include "GrenadeObject.h"
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include "include.h"

GrenadeObject::GrenadeObject( TextureManager * textureManager,
				   Vector2D position, 
				   Vector2D velocity,
				   Vector2D acceleration,
				   float rotation,
				   float angularVelocity,
				   float angularAcceleration,
				   float mass,
				   float fuseTime,
				   float strength,
				   bool explodeOnContact,
				   bool isArmed)
: Object(textureManager, new Material("grenade",0,0,true,0.25,-1), 0.0, position, velocity, acceleration, NULL, 0, 
		 rotation, angularVelocity, angularAcceleration, mass, false)
				
{
	this->isArmed = isArmed;
	if(textureManager)
	{
		if(!textureManager->LoadTexture(GRENADE_TEXTURE))
				printf("Loading %s failed!", GRENADE_TEXTURE);
		if(!textureManager->LoadTexture(EXPLOSION_TEXTURE))
				printf("Loading %s failed!", EXPLOSION_TEXTURE);
				
		material->SetTextureIndex(textureManager->TextureIndex(GRENADE_TEXTURE));
		explosionIndex = textureManager->TextureIndex(EXPLOSION_TEXTURE);
	}
	objectId = GRENADE_OBJECT_CLASS;
	this->fuseTime = fuseTime;
	this->explodeOnContact = explodeOnContact;
	this->explosionTime = 0.1;
	this->strength = strength;
	totalExplosionTime = this->explosionTime;
	
	vertices = (Vector2D*)malloc(sizeof(Vector2D) * 4);
	vertices[0] = Vector2D(-2,2);
	vertices[1] = Vector2D(2,2);
	vertices[2] = Vector2D(2,-2);
	vertices[3] = Vector2D(-2,-2);
	
	numVertices = 4;
	
	CalculateMomentOfInertia();
	CalculateTextureVertices(0.0);
}
GrenadeObject::GrenadeObject( 	TextureManager * textureManager,
				   			 	Vector2D position, 
								Vector2D velocity,
							   	Vector2D acceleration,
							   	float rotation,
							  	float angularVelocity,
							   	float angularAcceleration,
							   	float mass,
							   	float fuseTime,
							   	float strength,
							   	bool explodeOnContact)
: Object(textureManager, new Material("grenade",0,0,true,0.25,-1), 0.0, position, velocity, acceleration, NULL, 0, 
		 rotation, angularVelocity, angularAcceleration, mass, false)
{
	isArmed = true;
	if(textureManager)
	{
		if(!textureManager->LoadTexture(GRENADE_TEXTURE))
				printf("Loading %s failed!", GRENADE_TEXTURE);
		if(!textureManager->LoadTexture(EXPLOSION_TEXTURE))
				printf("Loading %s failed!", EXPLOSION_TEXTURE);
				
		material->SetTextureIndex(textureManager->TextureIndex(GRENADE_TEXTURE));
		explosionIndex = textureManager->TextureIndex(EXPLOSION_TEXTURE);
	}
	objectId = GRENADE_OBJECT_CLASS;
	this->fuseTime = fuseTime;
	this->explodeOnContact = explodeOnContact;
	this->explosionTime = 0.1;
	this->strength = strength;
	totalExplosionTime = this->explosionTime;
	
	vertices = (Vector2D*)malloc(sizeof(Vector2D) * 4);
	vertices[0] = Vector2D(-2,2);
	vertices[1] = Vector2D(2,2);
	vertices[2] = Vector2D(2,-2);
	vertices[3] = Vector2D(-2,-2);
	
	numVertices = 4;
	
	CalculateMomentOfInertia();
	CalculateTextureVertices(0.0);
}
void GrenadeObject::Arm()
{
	isArmed = true;
}
GrenadeObject::~GrenadeObject()
{
	printf("Deleting grenade object\n");
	if(vertices)
		delete(vertices);
	vertices = NULL;
	//printf("Deleting grenade2\n");
	if(keyPointList)
		free (keyPointList);
	keyPointList = NULL;
	//printf("Deleting grenade3\n");
	if(textureVertices)
		free (textureVertices);
	textureVertices = NULL;
	if(material)
		delete(material);
	material = NULL;
	//printf("Deleting grenade4\n");
	numVertices = 0;
	printf("done deleting grenade object\n");
}
bool GrenadeObject::ExplosionCollide(Object * object2, double elapsedTime)
{
	if(object2->position.dist(position) < 10)
	{
		Vector2D direction = (object2->position - position);
		direction = !direction;
		direction = direction * strength;
		object2->AddForce(direction);
	
		object2->AddDamage(20);
		return true;	
	}
	return false;
}
				   
bool GrenadeObject::IsFuseExpired()
{
	return fuseTime <= 0.0;
}
bool GrenadeObject::IsDone()
{
	//printf("IsFuseExpired = %d\n", IsFuseExpired());
	//printf("explosionTime <= 0 = %d\n", explosionTime <= 0.0);
	bool isDone = (explosionTime <= 0.0);
	//printf("fuseTime = %f, explosionTime = %f, isDone = %d\n", fuseTime, explosionTime, isDone);
	
	if(isDone)
	{
		//printf("HERE!!!\n");
		objectToDestroy = this;
	}
	return isDone;
}
void GrenadeObject::CollidedWith(Object * object2, float power, Vector2D point)
{
	if(explodeOnContact)
	{
		fuseTime = 0.0;
	}	
}

bool GrenadeObject::PreThinkEntryPoint(double elapsedTime)
{
	if(isArmed)
	{
		if(IsFuseExpired())
		{
			
			explosionTime -= elapsedTime;
			fuseTime = 0.0;
			//printf("----explosionTime = %f, fuseTime = %f\n", explosionTime, fuseTime);
			IsDone();
			//we asploded
			return true;	
		}
		
		fuseTime -= elapsedTime;
		//printf("---fuseTime = %f\n", fuseTime);
	
		
		if(fuseTime <= 0)
			letMeGo = true;
	}
	return false;
}
bool GrenadeObject::PreDrawEntryPoint()
{

	if(IsFuseExpired())
	{
		//we asploded
		material->SetTextureIndex(explosionIndex);
		CalculateExplosionVertices();
		glEnable(GL_BLEND);
		float alpha = explosionTime/totalExplosionTime;
		if(alpha < 0)
			alpha = 0;
		glColor4f(1,1,1, alpha);
		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
		return false;
	}
	return false;
}
void GrenadeObject::CalculateExplosionVertices()
{
	if(numVertices <= 0)
		return;
	
	float theta = 3.14159 * 0.5;
	float sinTheta = sin(theta);
	float cosTheta = cos(theta);
	
	if(explosionTime < 0)
		explosionTime = 0;
	float size = 5.0 - explosionTime/totalExplosionTime * 4.5;
	
	for(int i = 0; i < numVertices; i++)
	{
		float newX = vertices[i].x * cosTheta - vertices[i].y * sinTheta;
		float newY = vertices[i].y * cosTheta + vertices[i].x * sinTheta;

		vertices[i].x = newX;
		vertices[i].y = newY;
		vertices[i] = !(vertices[i]) * size;
	}	
}
void GrenadeObject::ReleasingObject()
{
	//Arm();
}
void GrenadeObject::PickingUpObject()
{
	Arm();
}